package com.dbappsecurity.bifrost.view;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Toast;
import butterknife.BindView;
import cn.jpush.android.api.JPushInterface;
import cn.sharesdk.framework.Platform;
import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.BDLocation;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.dbapp.uilib.widget.titlebar.TitleBar;
import com.dbappsecurity.bifrost.BuildConfig;
import com.dbappsecurity.bifrost.R;
import com.dbappsecurity.bifrost.base.InjectBaseFragment;
import com.dbappsecurity.bifrost.entity.ShareContent;
import com.dbappsecurity.bifrost.mgr.ShareMgr;
import com.dbappsecurity.jsbridge.JsBaseFragment;
import com.dbappsecurity.jsbridge.JsPermissionProcessor;
import com.dbappsecurity.jsbridge.entity.jsBaseItem;
import com.dbappsecurity.jsbridge.entity.jsThirdTitle;
import com.dbappsecurity.jsbridge.webview.CompletionHandler;
import com.google.gson.Gson;
import com.tbruyelle.rxpermissions2.RxPermissions;
import io.reactivex.Observable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import javax.inject.Inject;
import org.json.JSONObject;
import org.parceler.Parcels;

import static android.app.Activity.RESULT_OK;
import static com.dbapp.uilib.widget.titlebar.TitleBar.OptionItem.TYPE_IMG_LOCAL;
import static com.dbapp.uilib.widget.titlebar.TitleBar.OptionItem.TYPE_IMG_NET;
import static com.dbapp.uilib.widget.titlebar.TitleBar.OptionItem.TYPE_TXT;
import static com.dbapp.uilib.widget.titlebar.TitleBar.POS_LEFT;
import static com.dbapp.uilib.widget.titlebar.TitleBar.POS_RIGHT;

public class MainFragment extends InjectBaseFragment {

  public static final int QR_REQUEST = 10001;
  public static final int THIRD_ACTIVITY_REQUEST = 10002;

  @BindView(R.id.title_bar) TitleBar mTitleBar;
  LocationClient mLocationClient;
  MyLocationListener myLocationListener;

  @Inject
  public MainFragment() {
  }

  @Override
  protected int getLayout() {
    return R.layout.fragment_main;
  }

  JsBaseFragment mJsBaseFragment = new JsBaseFragment() {
    @Override
    protected Activity getActivity() {
      return MainFragment.this.getActivity();
    }

    @Override
    protected RxPermissions getRxPermissions() {
      return MainFragment.this.permissions.get();
    }

    @Override
    public void initViewView() {
      mGson = new Gson();
    }

    @Override
    protected String loadUrl() {
      if (getArguments() == null|| getArguments().getString("url")==null || getArguments().getString("url").equals(""))
        return BuildConfig.CONFIG_ENDPOINT;
      else
        return getArguments().getString("url");
    }

    @Override
    public void scan(jsThirdTitle jsthirdtitle, CompletionHandler handler) {
      requestPermissions(new JsPermissionProcessor(mPermissionListener) {
        @Override
        public void accept(String permissionName) {
          Intent intent = new Intent(getActivity(), QRActivity.class);
          mQrHandler = handler;
          Bundle bundle = new Bundle();
          Parcelable p = Parcels.wrap(jsthirdtitle);
          bundle.putParcelable("jsThirdTitle", p);
          intent.putExtras(bundle);
          startActivityForResult(intent, QR_REQUEST);
        }
      }, Manifest.permission.CAMERA);
    }

    @Override
    public void thirdPartyWeb(jsThirdTitle jsthirdtitle, CompletionHandler handler) {
      Intent intent = new Intent(getActivity(), ThirdActivity.class);
      Bundle bundle = new Bundle();
      Parcelable p = Parcels.wrap(jsthirdtitle);
      bundle.putParcelable("jsThirdTitle", p);
      intent.putExtras(bundle);
      startActivityForResult(intent, THIRD_ACTIVITY_REQUEST);
    }

    @Override
    public void share(JSONObject jsonObject, CompletionHandler handler) {
      ShareContent shareContent = getGson().fromJson(jsonObject.toString(),ShareContent.class);
      Log.i("MainFragment", "Arirus share: "+shareContent);
      ShareMgr.INS.share(shareContent, new ShareMgr.ShareListener() {
        @Override
        public void OnShareSuccess(Platform platform) {
          Log.i("MainFragment", "Arirus OnShareSuccess: "+platform);
          Map<String, String> map = new HashMap<>();
          map.put("platform", shareContent.platform);
          map.put("result", "success");
          JSONObject jsonObject = new JSONObject(map);
          handler.complete(jsonObject);
        }

        @Override
        public void OnShareFail() {
          Log.i("MainFragment", "Arirus OnShareFail: ");
          Map<String, String> map = new HashMap<>();
          map.put("platform", shareContent.platform);
          map.put("result", "failed");
          JSONObject jsonObject = new JSONObject(map);
          handler.complete(jsonObject);
        }

        @Override
        public void OnShareCancel() {
          Log.i("MainFragment", "Arirus OnShareCancel: ");
          Map<String, String> map = new HashMap<>();
          map.put("platform", shareContent.platform);
          map.put("result", "cancel");
          JSONObject jsonObject = new JSONObject(map);
          handler.complete(jsonObject);
        }
      });
    }

    @Override
    public void location(CompletionHandler handler) {
      mLocationHandler = handler;
      mLocationClient.start();
    }

    @Override
    public void pushTags(List<String> tags, CompletionHandler handler) {
      if (tags == null || tags.size() == 0) {
        handler.complete(failed());
        return;
      }
      Set<String> set = new HashSet<>(tags.size());
      Observable.fromIterable(tags).blockingSubscribe(set::add);
      JPushInterface.setTags(Objects.requireNonNull(getContext()), set,
          (i, s, set1) -> handler.complete(i == 0 ? success() : failed()));
    }

    @Override
    public void pushAlias(String alias, CompletionHandler handler) {
      if (alias == null) {
        handler.complete(failed());
        return;
      }
      JPushInterface.setAlias(Objects.requireNonNull(getContext()), alias, (i, s, set) -> {
        Log.i("MainFragment", "Arirus gotResult: " + i + " " + s + " ");
        handler.complete(i == 0 ? success() : failed());
      });
    }

    @Override
    public void pushClean(CompletionHandler handler) {
      JPushInterface.deleteAlias(Objects.requireNonNull(getContext()), 1);
      JPushInterface.cleanTags(getContext(), 2);
      handler.complete(success());
    }

    @Override
    public void chooseImage(JSONObject jsonObject, CompletionHandler handler) {
      handler.complete("webView 通常会通过 loadfile 直接上传文件，这个接口一般用不着，需要实现私聊");
    }

    @Override
    public void clickCustom(String index, CompletionHandler handler) {

    }

    @Override
    public void buttons(List<jsBaseItem> items, String type, CompletionHandler handler) {
      if (mTitleBar == null) return;

      int pos = POS_RIGHT;
      if (type.equals("left")) pos = POS_LEFT;

      mTitleBar.clean(pos);
      for (final jsBaseItem item : items) {
        int itemType = TYPE_TXT;
        String itemContent = item.getIconcontent();
        if (item.getIcontype().equals("title")) {
          itemType = TYPE_TXT;
        } else if (item.getIcontype().equals("image")) {
          itemType = TYPE_IMG_NET;
        } else if (item.getIcontype().equals("type")) itemType = TYPE_IMG_LOCAL;

        TitleBar.OptionItem optionItem =
            mTitleBar.addItem(pos, itemType, itemContent, item.getRedDot().equals("1"));
        if (optionItem != null) {
          optionItem.setOnClickListener(v -> {
            Map<String, String> map = new HashMap<>();
            map.put("index", "" + item.getTag());
            JSONObject jsonObject = new JSONObject(map);
            handler.setProgressData(jsonObject.toString());
          });
        }
      }
    }

    @Override
    public void menu(List<jsBaseItem> items, CompletionHandler handler) {
      Toast.makeText(getActivity(), "这里客户端没有实现，因为需要单独提供界面，如果需要实现，联系开发人员", Toast.LENGTH_SHORT)
          .show();
    }

    @Override
    public void title(String title) {
      if (mTitleBar != null) mTitleBar.setTitle(title);
    }

    @Override
    public void color(int color) {
      if (mTitleBar != null) mTitleBar.setBackgroundColor(color);
    }

    @Override
    public void titleBar(String toggle, CompletionHandler handler) {
      if (mTitleBar == null || handler == null) return;
      mTitleBar.setVisibility(toggle.equals("0") ? View.VISIBLE : View.GONE);
      handler.complete(success());
    }

    @Override
    public void titleClick(String toggle, CompletionHandler handler) {
      if (mTitleBar == null) return;
      if (toggle.equals("0")) {
        mTitleBar.setOnTitleClickListener(v -> handler.setProgressData("click"));
      } else {
        mTitleBar.removeOnTitleClickListener();
      }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
      super.onActivityResult(requestCode, resultCode, data);
      if (requestCode == QR_REQUEST) {
        Map map = new HashMap(1);
        if (resultCode == RESULT_OK
            && mQrHandler != null
            && data.getStringExtra("content") != null) {
          map.put("content", data.getStringExtra("content"));
        } else if (mQrHandler != null) {
          map.put("content", "cancel");
        }
        mQrHandler.complete(mGson.toJson(map));
      } else if (requestCode == THIRD_ACTIVITY_REQUEST && mThirdActivityHandler != null) {
        mThirdActivityHandler.complete(success());
      }
    }

    @Override
    protected void onPicDownload(String url) {
      requestPermissions(new JsPermissionProcessor(mPermissionListener) {
        @Override
        public void accept(String permissionName) {
          mApiClient.get().newDownload(url).start();
          Toast.makeText(getActivity(), "下载完成", Toast.LENGTH_SHORT).show();
        }
      }, Manifest.permission.WRITE_EXTERNAL_STORAGE);
    }
  };

  Gson mGson = null;

  CompletionHandler mLocationHandler = null;
  CompletionHandler mQrHandler = null;
  CompletionHandler mThirdActivityHandler = null;

  @Override
  public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    mJsBaseFragment.onViewCreated(view);
    initLocationOption(Objects.requireNonNull(getActivity()));
  }

  @Override
  public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    mJsBaseFragment.onActivityResult(requestCode, resultCode, data);
  }

  @Override
  public boolean onKeyDown(int keyCode, KeyEvent event) {
    return mJsBaseFragment.onKeyDown(keyCode, event) | super.onKeyDown(keyCode, event);
  }

  @Override
  public void onResume() {
    super.onResume();
    mJsBaseFragment.onResume();
  }

  @Override
  public void onPause() {
    super.onPause();
    mJsBaseFragment.onPause();
  }

  @Override
  public void onDestroyView() {
    super.onDestroyView();
    mJsBaseFragment.onDestroyView();
  }

  private void initLocationOption(Context context) {
    //定位服务的客户端。宿主程序在客户端声明此类，并调用，目前只支持在主线程中启动
    if (context == null) return;
    mLocationClient = new LocationClient(context.getApplicationContext());
    //声明LocationClient类实例并配置定位参数
    LocationClientOption locationOption = new LocationClientOption();
    myLocationListener = new MyLocationListener();
    //注册监听函数
    mLocationClient.registerLocationListener(myLocationListener);
    //可选，默认高精度，设置定位模式，高精度，低功耗，仅设备
    locationOption.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
    //可选，默认gcj02，设置返回的定位结果坐标系，如果配合百度地图使用，建议设置为bd09ll;
    locationOption.setCoorType("gcj02");
    locationOption.setIgnoreKillProcess(false);
    //可选，默认false，设置是否收集CRASH信息，默认收集
    locationOption.SetIgnoreCacheException(true);
    //可选，默认false，设置是否开启Gps定位
    locationOption.setOpenGps(true);
    //可选，默认false，设置定位时是否需要海拔信息，默认不需要，除基础定位版本都可用
    //设置打开自动回调位置模式，该开关打开后，期间只要定位SDK检测到位置变化就会主动回调给开发者，该模式下开发者无需再关心定位间隔是多少，定位SDK本身发现位置变化就会及时回调给开发者
    locationOption.setOpenAutoNotifyMode();
    mLocationClient.setLocOption(locationOption);
    //开始定位
    mLocationClient.start();
  }

  public class MyLocationListener extends BDAbstractLocationListener {
    @Override
    public void onReceiveLocation(BDLocation location) {

      //获取纬度信息
      double latitude = location.getLatitude();
      //获取经度信息
      double longitude = location.getLongitude();
      //获取定位精度，默认值为0.0f
      int errorCode = location.getLocType();
      Log.i("MyLocationListener",
          "Arirus onReceiveLocation: " + errorCode + " " + latitude + " " + longitude);
      if (mLocationHandler != null) {
        Map<String, Double> map = new HashMap<>(2);
        map.put("latitude", latitude);
        map.put("longitude", longitude);
        mLocationHandler.setProgressData(map);
      }
      mLocationClient.stop();
    }
  }
}
